#include "cv.h"

#include "utils.hh"


std::string get_basename (const char * name)
{

    std::string bn = name;

    size_t pos = bn.find_last_of("/");
    if(pos != std::string::npos)
	bn = bn.substr(pos+1, bn.size());
    
    pos = bn.find_last_of(".");
    if(pos != std::string::npos)
	bn.replace(pos, 1, "_");//remove the dot    }	
    
    return bn;
}



IplImage * preprocess_image(const IplImage *src_img)
{

    IplImage *img;


    if(src_img->depth != IPL_DEPTH_32F){ //i take for granted that it is 8U
	if(src_img->nChannels != 1){
	    IplImage *aux = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_32F, src_img->nChannels);
	    cvConvert(src_img, aux);	    
	    img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_32F, 1);
	    cvCvtColor(aux, img, CV_BGR2GRAY);

	    cvReleaseImage(&aux);
	}
	else{
	    img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_32F, 1);
	    cvConvert(src_img, img);
	     
	}
	

	cvScale(img, img, 1./255);
    }
    else{	

	double max, min;

	img = cvCloneImage(src_img);

	if(img->nChannels > 1){
	    for(int ai=1; ai<=img->nChannels; ai++){
		cvSetImageCOI(img, ai);
		cvMinMaxLoc(img, &min, &max);
		if(max > 1.){
		    cvResetImageROI(img);
		    cvScale(img, img, 1./255);
		    break;
		}
	    }
	    cvResetImageROI(img);
	}
	else{
	    cvMinMaxLoc(img, &min, &max);    
	    //I take for granted that if the pixels are not  in [0,1], then they are in [0,255].
	    if(max > 1.){
		cvScale(img, img, 1./255);
	    }
	}
    }

    {
	IplImage *aux = cvCreateImage(cvSize(400,400), img->depth, img->nChannels);
	cvResize(img, aux);
	cvReleaseImage(&img);
	img = aux;
    }
    
    return img;

}

/*
int init_model_shapes(boost::shared_ptr<SMATModel>& smat, CvFileStorage *fs,
		      CvSeqReader& reader, const CvSeq* seq)
{
    
    if( cvGetSeqReaderPos( &reader ) == seq->total){
	std::cerr << "File ended, not all shapes initialized. Depth: " 
		  <<smat->m_depth << std::endl;
	exit(-1);
    }
    
    //advance in the sequence until a matrix is found
    
    while(!CV_IS_SET_ELEM(reader.ptr)){
	CV_NEXT_SEQ_ELEM( seq->elem_size, reader );
	if( cvGetSeqReaderPos( &reader ) == seq->total){
	    std::cerr << "File ended, not all shapes initialized. Depth: " 
		      <<smat->m_depth << std::endl;
	    exit(-1);
	}
    }
    
    //read the point for this model
    CvFileNode *node = (CvFileNode*)reader.ptr;
	    
    if(node){
	if(CV_NODE_IS_MAP(node->tag) && 
	   !strcmp(node->info->type_name, "opencv-matrix")){
	    
	    std::cout << cvGetFileNodeName( node ) << std::endl;

	    CvMat *A = (CvMat*) cvRead(fs, node); 
	    smat->shape->set_shape(A);
	    cvReleaseMat(&A);
	}       
    }
	    
    CV_NEXT_SEQ_ELEM( seq->elem_size, reader );

    for(uint ai=0; ai<smat->submodel_parents.size(); ai++){

	init_model_shapes(smat->submodels.at(ai), fs, reader, seq);
    }
    
    return 0;        
}
*/

double calc_prob(double val, const CvMat *pdf_samples)
{


    double m, s;
    CvScalar mean, stdv;

    if(pdf_samples->rows == 0)
	return 1.;

    cvAvgSdv(pdf_samples, &mean, &stdv);
    m = mean.val[0];
    s = stdv.val[0];
    
    if(s == 0)
	return 1.;
    
    return (1/sqrt(2*M_PI)/s) *exp( -0.5 * pow((m-val)/s, 2) );

}

double calc_prob(double val, std::vector<double>pdf_samples)
{


    CvMat *mat = cvCreateMat(pdf_samples.size(), 1, CV_64FC1);

    for(uint ai=0; mat->rows; ai++)
	cvmSet(mat, ai, 0, pdf_samples.at(ai));


    double v = calc_prob(val, mat);
    cvReleaseMat(&mat);


    return v;
}



int strtolower(char *dest, const char * ori)
{
    int i;
    i=0;
    while (ori[i] != '\0')
    {
	dest[i] = (char) tolower((int)ori[i]);
	i++;
    }
    dest[i] = '\0';
    return i;
}

